#include "downloadmanager.h"
#include "taskrecord.h"

#include <QFileInfo>
#include <QNetworkRequest>
#include <QNetworkReply>
#include <QString>
#include <QStringList>
#include <QTimer>
#include <QDebug>

DownloadManager::DownloadManager(QObject *parent)
    : QObject(parent), downloadedCount(0), totalCount(0), currentTask(0)
{
}

void DownloadManager::append(const QList<TaskRecord*> &taskList)
{
    foreach (TaskRecord* task, taskList)
        append(task);

    if (downloadQueue.isEmpty())
        QTimer::singleShot(0, this, SIGNAL(finished()));
}

void DownloadManager::append(TaskRecord* task)
{
    if (currentTask == 0 && downloadQueue.isEmpty())
        QTimer::singleShot(0, this, SLOT(startNextDownload()));

    downloadQueue.append(task);
    ++totalCount;
}

QString DownloadManager::saveFileName(const TaskRecord &task)
{
    QString path = task.getURL();
    qDebug() << path;
    QString basename = QFileInfo(path).fileName();
    qDebug() << basename;

    if (QFile::exists(task.getPath() + "/" + basename)) {

        int i = 0;
        basename += '.';
        while (QFile::exists(task.getPath() + "/" + basename + QString::number(i)))
            ++i;

        basename += QString::number(i);
    }

    return task.getPath() + "/" + basename;
}

void DownloadManager::startNextDownload()
{
    if (downloadQueue.isEmpty()) {
        qDebug() << downloadedCount << "/" << totalCount << " files downloaded successfully\n";
        emit finished();
        return;
    }

    int highestPriIndex = 0;
    int highestPri = downloadQueue[0]->getPriority();
    for (int i = 0; i < downloadQueue.count(); ++i) {
        if (downloadQueue[i]->getPriority() > highestPri) {
            highestPriIndex = i;
            highestPri = downloadQueue[i]->getPriority();
        }
    }
    currentTask = downloadQueue[highestPriIndex];
    downloadQueue.removeAt(highestPriIndex);

    QString filename = saveFileName(*currentTask);
    qDebug() << filename;

    output.setFileName(filename);
    if (!output.open(QIODevice::WriteOnly)) {
        currentTask = 0;
        startNextDownload();
        return;
    }

    currentTask->updateStatus(TaskRecord::DOWNLOADING);

    QNetworkRequest request(currentTask->getURL());
    currentDownload = manager.get(request);
    connect(currentDownload, SIGNAL(downloadProgress(qint64,qint64)), currentTask,
            SLOT(updateProgress(qint64,qint64)));
    connect(currentDownload, SIGNAL(finished()),
            SLOT(downloadFinished()));
    connect(currentDownload, SIGNAL(readyRead()),
            SLOT(downloadReadyRead()));

    downloadTime.start();
}

void DownloadManager::downloadFinished()
{
    //progressBar.clear();
    qDebug() << "Almost close.";
    output.close();

    if (currentDownload->error()) {
        // download failed
        qDebug() << "Failed: " << currentDownload->errorString();
        currentTask->updateStatus(TaskRecord::ERROR);
    } else {
        qDebug() << "Success.";
        currentTask->updateStatus(TaskRecord::COMPLETED);
        ++downloadedCount;
    }

    currentTask = 0;
    currentDownload->deleteLater();
    startNextDownload();
}

void DownloadManager::downloadReadyRead()
{
    output.write(currentDownload->readAll());
}
